home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 235_01 / ovdir.c < prev    next >
Text File  |  1987-06-16  |  25KB  |  735 lines

  1. /*  030  14-Feb-87  ovdir.c
  2.  
  3.         Copyright (c) 1987 by Blue Sky Software.  All rights reserved.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include "ov.h"
  8. #include "dosfile.h"
  9.  
  10. #define DCOLSIZ 15
  11. #define DCOLS (SCREEN_COLS / DCOLSIZ)
  12.  
  13. #define dr2sr(r) (FIRST_NROW + (r - drbase))
  14. #define dc2sc(c) ((c - dcbase) * DCOLSIZ)
  15.  
  16. #define TO_NONE 0
  17. #define TO_SUBDIR 1
  18. #define TO_SIBLING 2
  19. #define TO_PARENT 3
  20. #define TO_ROOT 4
  21.  
  22. char *strrchr(), *strupr();
  23. struct search_block *nxtfile();
  24.  
  25. struct dir_ent {
  26.    struct dir_ent *subdir;
  27.    struct dir_ent *sibling;
  28.    struct dir_ent *parent;
  29.    struct dir_ent *prev_sib;
  30.    char name[13];
  31.    unsigned char row;
  32.    unsigned char col;
  33. };
  34.  
  35. static last_drive = ' ';
  36. static int drow, dcol, ldrow;
  37. static char dirpath[MAX_PATHLEN+6];
  38. static int drbase, drend, dcbase, dcend;
  39. static struct dir_ent *curdir, *logdir, *findir();
  40. static struct dir_ent root = { NULL, NULL, NULL, NULL, "", 0, 0 };
  41.  
  42. int dir_exit(), dir_login(), dir_mkdir(), dir_rmdir(), dir_new();
  43. extern struct menu_selection top_file_menu[], *top_menu;
  44.  
  45. struct menu_selection top_dir_menu[] = {
  46.    { "Login", "Login (switch) to the highlighted directory", dir_login, NULL },
  47.    { "Mkdir", "Make a subdirectory of the highlighted directory", dir_mkdir, NULL },
  48.    { "New", "Reread and redisplay directory tree", dir_new, NULL },
  49.    { "Rmdir", "Remove (delete) the highlighted directory", dir_rmdir, NULL },
  50.    { "Quit", "Return to file display", dir_exit, top_file_menu },
  51.    { NULL, NULL, NULL, NULL }
  52. };
  53.  
  54. extern struct window cw;
  55. extern unsigned char dir_display, restricted;
  56. char *strchr();
  57.  
  58.  
  59. /******************************************************************************
  60.  **                            D T R E E                                     **
  61.  *****************************************************************************/
  62.  
  63. dtree() {              /* display / work with directory tree */
  64.  
  65.    int drive;
  66.  
  67.    dir_display = TRUE;                 /* dir tree is (will be) displayed */
  68.    restricted = TRUE;                  /* disable some file commands */
  69.  
  70.    /* scan the current disk and create the internal directory tree if it
  71.       hasn't already been built or the user has changed disks */
  72.  
  73.    if ((drive = current_drive()) != last_drive) {  /* has the drive switched? */
  74.  
  75.       if (root.subdir) {                       /* delete current tree */
  76.          del_dtree(root.subdir);               /* if drive switch */
  77.          root.subdir = NULL;
  78.       }
  79.  
  80.       last_drive = drive;
  81.  
  82.       *dirpath = '\0';                         /* scan_dir() starts at */
  83.       strncat(dirpath,cw.dirbuf,3);            /*   drives root dir */
  84.       strcpy(root.name,dirpath);
  85.  
  86.       disp_msg(1,"Scanning disk");             /* takes awhile, tell user */
  87.  
  88.       scan_dir(&root);                         /* build new dir tree */
  89.  
  90.       clr_msg();                               /* done scanning */
  91.  
  92.       drbase = dcbase = 0;                     /* assume dir */
  93.       drend = NAME_ROWS;                         /* will start */
  94.       dcend = DCOLS;                               /* at the root */
  95.  
  96.       curdir = findir();                       /* locate current dir in tree */
  97.  
  98.    } else {            /* don't need to scan the disk */
  99.  
  100.       curdir = findir();               /* point to logged in dir */
  101.       adj_dir_dis();                   /* make sure logged dir will show */
  102.    }
  103.  
  104.    logdir = curdir;                    /* remember the logged dir */
  105.  
  106.    /* now display the current portion of the dir tree */
  107.  
  108.    show_tree();                        /* let user see it */
  109.  
  110.    /* this is a hack, but... if a new drive was scanned, we don't know for
  111.       sure if the curent dir is really displayed because the row/column
  112.       values aren't calculated until it's actully displayed.  If the
  113.       user has more than a screen's worth of directories and he is in one
  114.       of the ones off screen, adjust the offsets and redisplay, sigh... */
  115.  
  116.    if (adj_dir_dis())
  117.       show_tree();
  118.  
  119.    top_menu = top_dir_menu;    /* setup the dir menu as the main menu */
  120. }
  121.  
  122.  
  123. /******************************************************************************
  124.                               D I R _ N E W
  125.  *****************************************************************************/
  126.  
  127. dir_new() {            /* rescan the disk and redisplay the dir tree */
  128.  
  129.    last_drive = ' ';   /* simply force a rescan */
  130.    dtree();            /*   and let dtree() do the work */
  131.    update_vol_stats(); /* in case its a new volume */
  132. }
  133.  
  134.  
  135. /******************************************************************************
  136.  **                       D I R _ E X I T                                    **
  137.  *****************************************************************************/
  138.  
  139. dir_exit() {           /* exit the dir display, return to file display */
  140.  
  141.    dir_display = FALSE;                /* dir tree will not be displayed */
  142.    restricted = FALSE;                 /* allow all file commands */
  143.  
  144.    top_menu = top_file_menu;           /* file menu is main again */
  145.  
  146.    update_header();                    /* always rewrite the entire screen */
  147.    refresh_screen(0);                  /* 'cause there may be > windows */
  148. }
  149.  
  150.  
  151. /******************************************************************************
  152.  **                         S C A N _ D I R                                  **
  153.  *****************************************************************************/
  154.  
  155. scan_dir(dp)           /* scan the specified dir tree for other directories */
  156. struct dir_ent *dp;
  157. {
  158.    int dplen;
  159.    int firsttime = TRUE;
  160.    struct search_block *sbp;
  161.    register struct dir_ent *ndp, *ldp = NULL;
  162.  
  163.    /* build the pathname of the dir to scan */
  164.  
  165.    dplen = strlen(dirpath);                    /* remember callers length */
  166.    if (strcmp(dp->name+2,"\\") != 0) {         /* special case if root dir */
  167.       strcat(dirpath,dp->name);                /* add name of dir to scan */
  168.       strcat(dirpath,"\\");
  169.    }
  170.    strcat(dirpath,"*.*");                      /* add wildcard string */
  171.  
  172.    /* scan all files in directory looking for subdirectories.  When a
  173.       subdirectory is found, add it to the dir_ent tree.  Note, the . and
  174.       .. directory entries are ignored. */
  175.  
  176.    while (sbp = nxtfile(dirpath,0x16,&firsttime))
  177.       if (sbp->attrib & DIR && *sbp->fn != '.') {
  178.  
  179.          /* found a subdir we want, build a struct dir_ent for it */
  180.          ndp = (struct dir_ent *) Malloc(sizeof(struct dir_ent));
  181.          strcpy(ndp->name,sbp->fn);
  182.          ndp->subdir = NULL;
  183.          ndp->sibling = NULL;
  184.          ndp->parent = dp;
  185.          ndp->prev_sib = ldp;
  186.  
  187.          /* now link it to the dir_ent tree either as a subdir of the
  188.             parent (1st one only) or a sibling of the last one */
  189.  
  190.          if (ldp)
  191.             ldp->sibling = ndp;        /* not 1st, is a sibling */
  192.          else
  193.             dp->subdir = ndp;          /* 1st one, subdir of parent */
  194.  
  195.          ldp = ndp;                    /* new one is now the last one */
  196.       }
  197.  
  198.    /* if any subdirectories were found, scan 'em.  This isn't done
  199.       earlier so the file search isn't complicated by the directory
  200.       switches. */
  201.  
  202.    if (ldp) {                            /* NULL if no sub's found */
  203.       dirpath[strlen(dirpath)-3] = '\0'; /* remove *.* for next level */
  204.       ldp = dp->subdir;                  /* start with the first one */
  205.       do {
  206.          scan_dir(ldp);                /* call ourselves to scan this subtree */
  207.       } while (ldp = ldp->sibling);    /* do all the subs found */
  208.    }
  209.  
  210.    dirpath[dplen] = '\0';              /* restore dir pathname for caller */
  211. }
  212.  
  213.  
  214. /******************************************************************************
  215.  **                           D E L _ D T R E E                              **
  216.  *****************************************************************************/
  217.  
  218. del_dtree(dp)          /* purge the current in memory dir tree structure */
  219. register struct dir_ent *dp;
  220. {
  221.  
  222.    register struct dir_